package com.dragon.modules.yuegou.service.impl.coupon;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.common.web.PageRequest;
import com.dragon.modules.yuegou.entity.coupon.CouponTemplateStockEntity;
import com.dragon.modules.yuegou.entity.coupon.CouponTemplateStockRecordEntity;
import com.dragon.modules.yuegou.entity.coupon.WelfareEntity;
import com.dragon.modules.yuegou.entity.coupon.WelfareRecordEntity;
import com.dragon.modules.yuegou.enums.code.CouponCode;
import com.dragon.modules.yuegou.enums.code.MemberCode;
import com.dragon.modules.yuegou.enums.coupon.CouponSourceType;
import com.dragon.modules.yuegou.enums.coupon.CouponTemplateStockRecordType;
import com.dragon.modules.yuegou.enums.coupon.CouponTemplateTimeLimitType;
import com.dragon.modules.yuegou.enums.coupon.WelfareCouponType;
import com.dragon.modules.yuegou.enums.coupon.WelfareStatus;
import com.dragon.modules.yuegou.mapper.coupon.WelfareMapper;
import com.dragon.modules.yuegou.model.coupon.Coupon;
import com.dragon.modules.yuegou.model.coupon.CouponTemplate;
import com.dragon.modules.yuegou.model.coupon.Welfare;
import com.dragon.modules.yuegou.model.coupon.WelfareCouponReceiveResponse;
import com.dragon.modules.yuegou.model.coupon.WelfareRecord;
import com.dragon.modules.yuegou.query.coupon.WelfareQuery;
import com.dragon.modules.yuegou.query.coupon.WelfareRecordQuery;
import com.dragon.modules.yuegou.service.coupon.CouponService;
import com.dragon.modules.yuegou.service.coupon.CouponTemplateService;
import com.dragon.modules.yuegou.service.coupon.CouponTemplateStockRecordService;
import com.dragon.modules.yuegou.service.coupon.CouponTemplateStockService;
import com.dragon.modules.yuegou.service.coupon.WelfareRecordService;
import com.dragon.modules.yuegou.service.coupon.WelfareService;
import com.dragon.modules.yuegou.web.Check;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * 优惠券福利信息表 服务实现
 *
 * @author pbuilder generated
 * @date 2019-10-14 15:15:00
 * @version 2.0
 */
@Slf4j
@Service("coupWelfareService")
public class WelfareServiceImpl
		extends ServiceImpl<WelfareMapper, WelfareEntity>
		implements WelfareService {

	@Autowired
	private CouponService couponService;
	@Autowired
	private WelfareRecordService welfareRecordService;

	@Autowired
	private CouponTemplateService couponTemplateService;

	@Autowired
	private CouponTemplateStockService couponTemplateStockService;

	@Autowired
	private CouponTemplateStockRecordService couponTemplateStockRecordService;


	@Override
	public IPage<Welfare> searchList(PageRequest page, String memberId, String busdId) {
		Check.notEmpty(busdId,"商圈id不能为空！！");
		IPage<Welfare> welfareIPage = new Page<>(page.getPage(),page.getSize(),page.getCount());
		IPage<Welfare> page1 = baseMapper.searchList(welfareIPage,busdId);
		List<Welfare> records = page1.getRecords();
		for (Welfare welfareRecord : records) {
			if (StringUtils.isNotEmpty(memberId)){
				WelfareRecordQuery welfareRecordQuery = new WelfareRecordQuery();
				welfareRecordQuery.setMemberId(memberId);
				welfareRecordQuery.setWelfareId(welfareRecord.getId());
				List<WelfareRecordEntity> list = welfareRecordService.list(welfareRecordQuery.toQueryWrapper());
				if (CollectionUtils.isEmpty(list)){
					welfareRecord.setAcquire("0");
				}else {
					List<WelfareRecordEntity> collect = this.getWelfareRecord(list);

					this.setAcquire(welfareRecord,collect,list);
				}
			}else {
				welfareRecord.setAcquire("0");
			}
			welfareRecord.setValidity(getValidity(welfareRecord));
		}
		return page1;
	}

	private void setAcquire(Welfare welfareRecord,List<WelfareRecordEntity> collect,List<WelfareRecordEntity> list){
		if (WelfareCouponType.PARK.equals(welfareRecord.getCouponType())) {
			if (CollectionUtils.isEmpty(collect) || Objects.isNull(welfareRecord.getNum()) || (welfareRecord.getNum() != -1 && collect.size() < welfareRecord.getNum())) {
				welfareRecord.setAcquire("0");
			} else {
				welfareRecord.setAcquire("1");
			}
		} else if (WelfareCouponType.DISCOUNTS.equals(welfareRecord.getCouponType())) {
			String couponTemplateId = welfareRecord.getCouponTemplateId();
			CouponTemplate couponTemplate = couponTemplateService.detail(couponTemplateId);
			if (welfareAcquire(couponTemplate,list)) {
				welfareRecord.setAcquire("0");
			} else {
				welfareRecord.setAcquire("1");
			}
		}
	}

	private List<WelfareRecordEntity> getWelfareRecord(List<WelfareRecordEntity> list){
		return list.stream().filter(a -> a.getReceiveTime().compareTo(LocalDate.now().atStartOfDay()) >= 0 && a.getReceiveTime().compareTo(LocalDate.now().plusDays(1).atStartOfDay().minusSeconds(1)) <= 0).collect(Collectors.toList());
	}

	private String getValidity(Welfare welfareRecord) {
		DateTimeFormatter df  = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		//停车券不变
		if (WelfareCouponType.PARK.equals(welfareRecord.getCouponType())) {
			return welfareRecord.getBeginTime().format(df) + " - " + welfareRecord.getEndTime().format(df);
		}
		//优惠券
		else if (WelfareCouponType.DISCOUNTS.equals(welfareRecord.getCouponType())) {
			String couponTemplateId = welfareRecord.getCouponTemplateId();
			CouponTemplate couponTemplate = couponTemplateService.detail(couponTemplateId);
			CouponTemplateTimeLimitType timeLimitType = couponTemplate.getTimeLimitType();
			//固定时间段
			if (CouponTemplateTimeLimitType.FIXED_RANGE.equals(timeLimitType)) {
				LocalDateTime startTime = couponTemplate.getStartTime();
				LocalDateTime endTime = couponTemplate.getEndTime();
				return startTime.format(df) + " - " + endTime.format(df);
			}
			//有效小时
			else if (CouponTemplateTimeLimitType.VALID_DAYS.equals(timeLimitType)) {
				Integer hours = couponTemplate.getValidHours();
				return "领取后" + hours + "小时后失效";
			}
		}
		return null;
	}

	private boolean welfareAcquire(CouponTemplate couponTemplate,List<WelfareRecordEntity> list) {
		//总限领
		Integer personalLimit = couponTemplate.getPersonalLimit();
		//每天限领
		Integer personalDayLimit = couponTemplate.getPersonalDayLimit();

		if (couponTemplate.getStatus() != 0){
			return false;
		}
		//都不限制
		if (personalDayLimit == -1 && personalLimit == -1) {
			return true;
		}
		//没有领取
		if (CollectionUtils.isEmpty(list)){
			return true;
		}

		if (personalDayLimit == -1) {
			//每天不限制，总数限制
			return list.size() < personalLimit ;
		} else if (personalLimit == -1) {
			//总数不限制，每天限制
			List<WelfareRecordEntity> collect = list.stream().filter(a -> a.getReceiveTime().compareTo(LocalDate.now().atStartOfDay()) >= 0 && a.getReceiveTime().compareTo(LocalDate.now().plusDays(1).atStartOfDay().minusSeconds(1)) <= 0).collect(Collectors.toList());
			return !(CollectionUtils.isNotEmpty(collect) && collect.size() >= personalDayLimit);
		} else {
			//都限制
			List<WelfareRecordEntity> collect = list == null ? null : list.stream().filter(a -> a.getReceiveTime().compareTo(LocalDate.now().atStartOfDay()) >= 0 && a.getReceiveTime().compareTo(LocalDate.now().plusDays(1).atStartOfDay().minusSeconds(1)) <= 0).collect(Collectors.toList());
			return !(CollectionUtils.isNotEmpty(collect) && collect.size() >= personalDayLimit)||(CollectionUtils.isNotEmpty(list) && list.size() >= personalLimit);
		}
	}

	@Override
	@Transactional
	public WelfareCouponReceiveResponse getWelfare(String memberId, String welfareId) {
		WelfareCouponReceiveResponse response = new WelfareCouponReceiveResponse();
		Check.notNull(memberId, MemberCode.MEMBER_ID_IS_EMPTY.getMessage());
		Check.notNull(welfareId, "福利id不能为空！！");
		WelfareEntity welfare = getById(welfareId);
		//福利为空
		if (Objects.isNull(welfare)){
			throw new DragonException(CouponCode.MEMBERSHIP_BENEFITS_HAVE_BEEN_SNAPPED_UP);
		}
		WelfareRecordQuery welfareRecordQuery = new WelfareRecordQuery();
		welfareRecordQuery.setWelfareId(welfareId);
		welfareRecordQuery.setMemberId(memberId);
		welfareRecordQuery.receiveTime().between(LocalDate.now().atStartOfDay(),
				LocalDate.now().plusDays(1).atStartOfDay().minusSeconds(1));
		List<WelfareRecordEntity> list = welfareRecordService.list(welfareRecordQuery.toQueryWrapper());
		 String couponTemplateId = welfare.getCouponTemplateId();
		response.setCouponTemplateId(couponTemplateId);
		response.setType(welfare.getCouponType().getCode());
		//停车券
		if (WelfareCouponType.PARK.equals(welfare.getCouponType())) {
			if (Objects.nonNull(list) && Objects.nonNull(welfare.getNum()) && list.size() >= welfare.getNum()) {
				response.setStatus(1);
				return response;
			}
			// 防止福利数据中当日领取数量字段为空
			if (Objects.isNull(welfare.getNum())) {
				welfare.setNum(1);
			}
			for (int i = 0; i < welfare.getNum(); i++) {
				Coupon coupon = couponService.createCoupon(null, memberId, couponTemplateId, CouponSourceType.WELFARE);

				WelfareRecord welfareRecord = new WelfareRecord();
				welfareRecord.setBusdId(welfare.getBusdId());
				welfareRecord.setWelfareId(welfare.getId());
				welfareRecord.setCouponTemplateId(couponTemplateId);
				welfareRecord.setMemberId(memberId);
				welfareRecord.setCouponId(coupon.getId());
				welfareRecord.setReceiveTime(LocalDateTime.now());
				welfareRecordService.save(welfareRecord);
			}
			response.setStatus(0);
		} else{
			//优惠券
			CouponTemplateStockEntity couponTemplateStock = couponTemplateStockService.getById(couponTemplateId);
			response.setStatus(0);
			// 判断是否还有库存
			if (couponTemplateStock == null || couponTemplateStock.getStockSurplus() < 1) {
				response.setStatus(2);
				return response;
			}
			//判断是否达到最大领取数量
			if (!couponTemplateService.verifyReceiveStatus(memberId, couponTemplateId)) {
				response.setStatus(1);
				return response;
			}
			// 给券给用户
			Coupon coupon = couponService.createCoupon(null, memberId, couponTemplateId, CouponSourceType.RECEIVE);
			// 扣库存
			couponTemplateStockService.editStock(couponTemplateId, -1);
			// 新增库存记录
			CouponTemplateStockRecordEntity stockRecordEntity = new CouponTemplateStockRecordEntity();
			stockRecordEntity.setType(CouponTemplateStockRecordType.RECEIVE);
			stockRecordEntity.setChange(1);
			stockRecordEntity.setCreatedBy(memberId);
			couponTemplateStockRecordService.save(stockRecordEntity);

			response.setCashFee(coupon.getReductionMount());
			//创建领取记录
			WelfareRecord welfareRecord = new WelfareRecord();
			welfareRecord.setBusdId(welfare.getBusdId());
			welfareRecord.setWelfareId(welfare.getId());
			welfareRecord.setCouponTemplateId(couponTemplateId);
			welfareRecord.setMemberId(memberId);
			welfareRecord.setCouponId(coupon.getId());
			welfareRecord.setReceiveTime(LocalDateTime.now());
			welfareRecordService.save(welfareRecord);
		}
		return response;
	}

	@Override
	public IPage<Welfare> search(PageRequest page, WelfareQuery quey) {
		IPage<WelfareEntity> welfareIPage = new Page<>(page.getPage(),page.getSize(),page.getCount());
		QueryWrapper<WelfareEntity> wrapper = quey.toQueryWrapper();
		wrapper.orderByDesc(WelfareEntity.COL_CREATED_TIME);
		IPage<WelfareEntity> page1 = baseMapper.selectPage(welfareIPage,wrapper);
		return page1.convert(Welfare::new);
	}

	@Override
	public void endWelfaret(String id) {
		Check.notNull(id,"商品id不能为空！！");
		WelfareEntity welfare = getById(id);
		if(welfare.getStatus().getCode() == WelfareStatus.OFF_SHELF.getCode()) {
			LocalDateTime beginTime = welfare.getBeginTime();
			LocalDateTime endTime = welfare.getEndTime();
			if(beginTime.isBefore(LocalDateTime.now()) && endTime.isAfter(LocalDateTime.now())) {
				welfare.setStatus(WelfareStatus.ON_SHELF);
			} else {
				throw new DragonException(CouponCode.NOT_IN_THE_TIME_FRAME);
			}
		} else {
			welfare.setStatus(WelfareStatus.OFF_SHELF);
		}
		baseMapper.updateById(welfare);
	}

	@Override
	public Long getCount(String welfaretId) {
		WelfareRecordQuery query = new WelfareRecordQuery();
		query.setWelfareId(welfaretId);
		return welfareRecordService.count(query.toQueryWrapper());
	}
}